package device

import (
	"context"
	"gitee.com/guolianyu/kit/skit/constants"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/go-kratos/kratos/v2/middleware/tracing"
	"github.com/google/uuid"
	"net"
	"net/http"
	"strings"
)

var trueClientIP = http.CanonicalHeaderKey(constants.HeaderTrueClientIP)
var xForwardedFor = http.CanonicalHeaderKey(constants.HeaderXForwardedFor)
var xRealIP = http.CanonicalHeaderKey(constants.HeaderXRealIP)

func realIP(r *http.Request) string {
	var ip string

	for _, ip = range strings.Split(r.Header.Get(xForwardedFor), ",") {
		ip = strings.TrimSpace(ip)
		if ip != "" && !isLocalIP(ip) {
			return ip
		}
	}
	ip = strings.TrimSpace(r.Header.Get(xRealIP))
	//if ip != "" && !isLocalIP(ip) {
	//	return ip
	//}
	if ip != "" {
		return ip
	}

	if ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)); err == nil {
		//if !isLocalIP(ip) {
		//	return ip
		//}
		return ip
	}
	return ""
}

// isLocalIP 检测 IP 地址字符串是否是内网地址
func isLocalIP(ip string) bool {
	return net.ParseIP(ip).IsLoopback()
}

func requestID(ctx context.Context, r *http.Request) string {
	if rid := r.Header.Get(HeaderRequestId); rid != "" {
		return rid
	}

	if rid, ok := log.Value(ctx, tracing.TraceID()).(string); ok {
		return rid
	}
	return uuid.NewString()
}
